﻿/*
 * powertable
 * Version: 1.1.3
 * License: New BSD License
 * Date: 2009/2/26
 * Author: Kim Wang
 * Email: wxnet2008@gmail.com
 * */

function table(ids)
{
	
//这里是一些配置信息:
//列输入框的类型

var tdEditopt = {};

//不同表格下拉列表框内容
/*
var selectText = {
	"table1": ["dddd","dddd","dddd"],
	"table2": ["sss","dd","dxxxx"],
	"table3": ["mm","mmm","llllll"],
	"table4":["测试内容","测试内容"]
	};
*/

var selectText = {};

//多个可以编辑表格的id列表
var tableids = ids,//"";

//当前单元格
ctdElem,

//上次操作的对象
oldobj,

//当前表格对象昂	
ctable,

//当前行对象
cRow,

//只读单元格集合
readOnlyTds=[],

//当前列号
cellIndex,

//创建输入框事件
oncreate,

//移除输入框事件
onreset,

//是否允许编辑
enableEdit = false,

//是否开启验证
enableva = false,

//列验证规则
cellvarule=null,
//弹出层对象
oPopup=null,

//针对不同的表格设置多个popup对象
oPopups = null;

/*
 *添加行和列
 * */

//添加新行
//newRow(行数)
function newRow(n,trElem,p){
	//行数
	n = n || 1;
	
	//当前元素
	trElem = trElem || last(tag("tbody",ctable)[0]);

	//要插入新节点位置(1为节点前)
	p = p || 0;

	//返回新建行的数组
	var temp = [],
	
	row = null;
	
	//创建行
	function _newRow()
	{
		
		var ele = tag("tr",ctable)[0].cloneNode(true);				

		//设置值为空
		each(tag("td",ele),function(){
			
			//将单元格的值设为空
			this.innerHTML = "&nbsp;";
			this.style.backgroundColor = "#ffffff";
		
		});

		return ele;	
	}

	//添加行
	for(var i=0;i<n;i++)
	{	
		
		row = _newRow();
		
		if (p==1)
		
			before(tag("tbody",ctable)[0],trElem,row);
		
			 
		
		else
			after(row,trElem);

		
		temp.push(row);
	
	}

	return temp;
}


//新建列
function newColumn()
{
	each(tag("tr"), function() {
		var newtd = document.createElement("td");
		newtd.innerHTML = "&nbsp;";
    		this.appendChild(newtd);
	});
}

/*
 * 为表格添加编辑功能
 * */

//创建输入框
function createInput(elem,type)
{
    	var str = elem.innerHTML.trim();
	
	elem.innerHTML = "";

	var tempElem;

	switch(type)
	{
		case "text":
	        //创建文本框
	        tempElem = create("input");
		attr(tempElem, "id", "txvaid");
		attr(tempElem, "type", "text");
	        tempElem.style.width = "100%";
	        tempElem.style.height = "100%";
		append(elem, tempElem);
		setTimeout(function(){
			tempElem.focus();
		},0);
		

		//设置文本框的值为单元格内容
		tempElem.value = (str == "&nbsp;")? str.replace(/\&nbsp\;/gi,"") : str;
		
		break;

		case "select":
			//创建下拉列表框
		    	tempElem = create("select");
			attr(tempElem, "id", "txvaid");
			each(selectText[ctable.id],function(i,v){
				tempElem.options.add(new Option(v,0));
    			});
			
			append(elem,tempElem);

			setTimeout(function(){
			
				tempElem.focus();

			},0);
		break;

		case "textarea":
		    	tempElem = create("textarea");
		    	attr(tempElem, "id", "txvaid");
		    	tempElem.style.width = "100%";
		    	tempElem.style.height = "100%";
			append(elem,tempElem);

			setTimeout(function(){
			tempElem.focus();
			},0);
			//设置文本框的值为单元格内容
			tempElem.value = (str == "&nbsp;")? str.replace(/\&nbsp\;/gi,"") : str;
	
		break;
	}

}

//验证输入框
function vainput()
{
	
	if(!enableva) return;
	if(!ctdElem) return false;

	if(!document.getElementById("txvaid")) return false;

	if(!txjs.va.vamanager) {alert("没有引用验证框架脚本");return false;}

	//创建验证对象
	var vaobj = new txjs.va.vamanager(),

	//创建验证规则
	varule = {};

	varule["txvaid"] = cellvarule["td" + getcolNum(ctable,ctdElem)];

	//添加验证规则
	vaobj.addoption(varule);

	vaobj.validate(function() {});

	if(!vaobj.getisok()) 
		return false;
}

//获取td的列号
function getcolNum(tableElem,tdElem)
{
	var temp;
	for(var tri=0,trs = tag("tr",tableElem),trlen=trs.length;tri<trlen;tri++)
	{
		for(var tdi=0,tds=tag("td",trs[tri]),tdlen = tds.length;tdi<tdlen;tdi++)
		{
			
			if(tdElem === tds[tdi])
			{
				temp = tdi;
				break;
			}

			
		}
		
		if(!!temp)
			break;

	}

	return temp;
}

//表格中是否有某个值
function hasValue(value)
{
	var temp = false;
	
	each(tag("tr",ctable),function(){
		if (tag("td",this)[0].firstChild.nodeValue == value) 
			temp = true;
	});
	
	return temp;
}

//根据值获取行
function getRow(value)
{
	var temp = null;
	each(tag("tr",ctable),function(){
		if (tag("td",this)[0].firstChild.nodeValue == value) 
		temp = this;
	});
	return temp;
}

//恢复oldobj为非编辑状态
function resetObj(elem)
{
	if(!last(elem)) return;
	
	elem.innerHTML = (last(elem).tagName.toLowerCase()=="select") ?  

		last(elem).options[last(elem).options.selectedIndex < 0 ? 0 : last(elem).options.selectedIndex].text : 
		
		(last(elem).value == "" ? "&nbsp;" : last(elem).value);
}

//获取所有需要编辑单元格的列表
function tabList()
{
	var temp = [];
	       
	each(tableids.split(","),function(){
		each(tag("td",id(this + "")),function(){
			       
	 	temp.push(this);
		});
	});
	
	return temp;
}

//获取所有当前列的td数量
function celList(tableelem,tdelem)
{
		
	//表格列数
	var cellnum = tag("td",id(tableids.split(",")[0])).length / tag("tr",id(tableids.split(",")[0])).length,

	//td列表
	tdarr = tabList(),

	//表格行数
	rownum = tdarr.length / cellnum,

	//cellindex
	n = getcolNum(tableelem,tdelem),

	temp = [];
	
	for(i=0;i<rownum;i++)
	{
		temp.push(tdarr[n + (cellnum * i)]);
	}

	return temp;
}

//将一维数组转换为二维
//n为每个子数组元素的个数
function toArr(arr,n)
{
	var t = 0,
	temp = [];
	for(var i=0;i<arr.length;i++)
	{
		if(((i+1) % n)==0) temp.push(arr.slice(t,t+=n));
	}

	return temp;
}

//设置选中行颜色
function setcRowColor(row)
{
	if(!row) return;

	//设置选中行颜色
	each(tag("td",row),function(){
			addClass(this,"current");
	});
}

function clearcRowColor(row)
{
	if(!row) return;

	//清除上一行的颜色
	each(tag("td",row),function(){
			removeClass(this,"current");
	});
}

//修正firefox克隆textarea节点时，值丢失的bug
var areavalues = {};

function recordValue(parentElem)
{
	var elems = parentElem.getElementsByTagName("textarea");
	
	if(elems.length===0) return;

	//修正使用firefox克隆textarea时，value丢失的问题

	each(elems,function(i){
		areavalues["a"+i] = this.value;
	});
}

function resetValue(parentElem)
{
	var elems = parentElem.getElementsByTagName("textarea");
	
	if(elems.length===0) return;

	//修正使用firefox克隆textarea时，value丢失的问题

	each(elems,function(i){
		this.value = areavalues["a"+i];
		delete areavalues["a"+i];
	});
}

/*
 * 事件处理
 * */

//表格单击事件
function tableClick(e)
{
	e.stopPropagation();


		
		
		ctable = this;
		
		tarObj = e.target || e.srcElement,

		//列编辑类型
		tdEditType = null;

		//只处理单元格td
		if (tarObj.tagName == "TD")
		{

			//记录当前行
			cRow = parent(tarObj);

			//记录当前列号
			cellIndex = getcolNum(ctable,tarObj);

			

			//恢复上次表格内容
			if(!!oldobj){
					resetObj(oldobj);
					clearcRowColor(parent(oldobj));
			}

			//设置颜色
			setcRowColor(cRow);
				

			ctdElem = tarObj;

			//获取当前列的编辑类型
			tdEditType = tdEditopt["td"+cellIndex] || "text";

			//是否存在输入控件
			if(!last(tarObj) && !readOnlyTds.inArray(tarObj))
			{

				createInput(ctdElem,tdEditType);

			}
			//弹出层设置值方式
			if((oPopups || oPopup) && getPopup(this.id) && readOnlyTds.inArray(tarObj)) {
				getPopup(this.id).build();
				getPopup(this.id).show();
			}
					
			
		
			//记录本次操作的对象
			oldobj = ctdElem;

			
	}
}

//表格键盘事件
function tableKeyDown(e)
{
		var tarObj = e.target || e.srcElement;

		//td列表
		var arr;

		//输入状态下，获取td对象
		var tdObj = tarObj.tagName.toLowerCase() != "td" ? parent(tarObj) : tarObj;

		//设置当前表格
		ctable = parent(tdObj,3);

		//当前单元格在数组中的位置
		var n;

		//下一个单元格
		var nextTd;

		//编辑类型
		var tdEditType;

		var i=0,len=0;

		//回车键
		if(e.keyCode == 13) {
			//验证输入
			if(vainput()===false) return;	       
			resetObj(ctdElem);
			//清除上一行的颜色
			clearcRowColor(parent(ctdElem));

			ctdElem = null;
		}
					
					
		//tab键
		if(e.keyCode == 9) {


			e.preventDefault();	
			
			arr = tabList();
			
			for(i = 0,len=arr.length;i<len;i++)
			{


				if(  tdObj=== arr[i]){
					n = i;
					break;
				}
			}			       
			
			resetObj(ctdElem);

			//清除上一行的颜色
			clearcRowColor(parent(ctdElem));			
		
			//下一个单元格
			nextTd = ctdElem = arr[((n + 1) == arr.length)?0:n+1];

			//设置选中行颜色
			setcRowColor(parent(nextTd));

			cRow = parent(nextTd);

			//记录列号
			cellIndex = getcolNum(ctable,nextTd);
			
	
			tdEditType = tdEditopt["td"+getcolNum(parent(tdObj,2),nextTd)] || "text";

			

			if(!readOnlyTds.inArray(nextTd))
				//设置内容
				createInput(nextTd, tdEditType);

			oldobj = nextTd;
					
		}
		
		//向左
		if(e.keyCode == 37 && tarObj.value == ""){
			//alert("左");
			
			//当前列
			arr = tag("td",parent(tdObj));

			
			

			for(i = 0,len=arr.length;i<len;i++)
			{
				

				if(  tdObj=== arr[i]){
					n = i;
					break;
				}
			}			
			
			resetObj(ctdElem);

			//下一个单元格
			nextTd = ctdElem = arr[((n - 1) < 0) ? arr.length - 1 : n - 1];

			tdEditType = tdEditopt["td"+getcolNum(parent(tdObj,2),nextTd)] || "text";

			if(!readOnlyTds.inArray(nextTd))
				//设置内容
 				createInput(nextTd, tdEditType);

			oldobj = nextTd;
		}

		//向上
		if(e.keyCode == 38){
			//alert("上");

			//当前列
			arr = celList(ctable,tdObj);
			

			for(i = 0,len=arr.length;i<len;i++)
			{
				

				if(  tdObj=== arr[i]){
					n = i;
					break;
				}
			}

			if(vainput()===false) return;

			resetObj(ctdElem);

			//清除上一行的颜色
			clearcRowColor(parent(ctdElem));

			//下一个单元格
			nextTd = ctdElem = arr[((n - 1) < 0) ? arr.length - 1 : n - 1];

			
			//设置选中行颜色
			setcRowColor(parent(nextTd));

			//下一行
			cRow = parent(nextTd);
			
			tdEditType = tdEditopt["td"+getcolNum(parent(tdObj,2),tdObj)] || "text";

			if(!readOnlyTds.inArray(nextTd))
				//设置内容
 				createInput(nextTd, tdEditType);

			oldobj = nextTd;
		}

		//向右	
		if(e.keyCode == 39 && tarObj.value == ""){
			//alert("右");

			//当前列
			arr = tag("td",parent(tdObj));

			for(i = 0,len=arr.length;i<len;i++)
			{
				

				if(  tdObj=== arr[i]){
					n = i;
					break;
				}
			}			

			resetObj(ctdElem);

			//下一个单元格
			nextTd = ctdElem = arr[((n + 1) == arr.length)?0:n+1];
			
			cRow = parent(nextTd);
			

			tdEditType = tdEditopt["td"+getcolNum(parent(tdObj,2),nextTd)] || "text";

			if(!readOnlyTds.inArray(nextTd))
				//设置内容
 				createInput(nextTd, tdEditType);

			oldobj = nextTd;
		
		}

		//向下
		if(e.keyCode == 40){
			//alert("下");

			//当前列
			arr = celList(ctable,tdObj);
			

			for(i = 0,len=arr.length;i<len;i++)
			{
				

				if(  tdObj=== arr[i]){
					n = i;
					break;
				}
			}			

			if(vainput()===false) return;

			resetObj(ctdElem);

			//清除上一行的颜色
			clearcRowColor(parent(ctdElem));

			//下一个单元格
			nextTd = ctdElem = arr[((n + 1) == arr.length)?0:n+1];

			//设置选中行颜色
			setcRowColor(parent(nextTd));
			
			
			tdEditType = tdEditopt["td"+getcolNum(parent(tdObj,2),tdObj)] || "text";

			if(!readOnlyTds.inArray(nextTd))
				//设置内容
 				createInput(nextTd, tdEditType);

			oldobj = nextTd;

		}
}

//document单击处理
function documentClick()
{
	
	if(!ctdElem) return;

	//验证输入
	if(vainput()===false) return;

	//恢复输入框
	resetObj(ctdElem);	

	//清除行的背景色
	clearcRowColor(parent(ctdElem));

	//重置当前单元格
	ctdElem = null;

}

//绑定表格事件
function bindEvent()
{
//循环注册事件
each(tableids.split(","),function(i,v){

	//表格键盘事件				
	addEvent(id(v + ""),"keydown",tableKeyDown);
	
	//表格单击事件
	addEvent(id(v + ""),"click", tableClick);

	//document单击事件
	addEvent(document,"click",documentClick);
});
}

//清除表格事件
function delEvent()
{
	
	each(tableids.split(","),function(i,v){


	//表格键盘事件	
				
	removeEvent(id(v + ""),"keydown",tableKeyDown);
	
	removeEvent(id(v + ""),"click", tableClick);


	removeEvent(document,"click",documentClick);

	

});

//关闭有存在的编辑
documentClick();

}

if(enableEdit)
{
	
	bindEvent();
}

/*
 *  公共方法
 */

//是否开启编辑
function edited()
{
	
	enableEdit = (!enableEdit) ? true : false;
	enableEdit ? bindEvent() : delEvent();
}

//移动行
//type为1，为向上移动
function moveRow(e,type)
{
	e.stopPropagation();

	if(!enableEdit) return;
	
	if(!ctdElem) return;
	
	recordValue(cRow);
	
	//复制单前行
	var rowElem = cRow.cloneNode(true);

	if(type)
	{
		
		var prevElem = prev(cRow);
		if(prevElem)
		{
			before(parent(cRow),prevElem,rowElem);
			remove(cRow);
			
			cRow = rowElem;

			
			ctdElem = tag("td",cRow)[cellIndex];
			oldobj = tag("td",cRow)[cellIndex];

			
		}
	}
	else
	{
	
		var nextElem = next(cRow);
		
		if(nextElem)
		{
			after(rowElem,nextElem);
			remove(cRow);
			cRow = rowElem;
			ctdElem = tag("td",cRow)[cellIndex];
			oldobj = tag("td",cRow)[cellIndex];
		}
	}

	resetValue(cRow);
}


//删除一行
function delRow()
{
	if(!enableEdit) return;

	if(!ctdElem) return;
	
	remove(cRow);
}

//在当前行上新建一行
function newTopRow()
{
	if(!ctdElem) return;
	if(!enableEdit) return;
	newRow(1,cRow,1);
}

//在当前行下新建一行
function newBottomRow()
{
	if(!ctdElem) return;
	if(!enableEdit) return;
	newRow(1,cRow);
}

//获取表格html
function getTableHtml()
{
	//加载表格时需要 replace(/<td><\/td>/gi,"<td>&nbsp;</td>");
	return id("dd").innerHTML.toLowerCase().replace	(/<td>\&nbsp\;<\/td>/gi,"<td></td>");
}


//获取表格数据(Array)
function getArrayData()
{
	//关闭有存在的编辑
	documentClick();
	
	//表格列数
	var cellnum = tag("td",id(tableids.split(",")[0])).length / tag("tr",id(tableids.split(",")[0])).length,
	
	//获取所有单元格数组
	arr = tabList();

	var temp = toArr(arr,cellnum);
	each(temp,function(){
		var arr = this;
		each(this,function(i,v){

			arr[i] = this.innerHTML.replace(/\&nbsp\;/gi,"");
		
		});	
	
	});

	//将表格转换为二维数组
	return temp;

}

//验证表格数据
function vaTableData()
{
	documentClick();
	var arr = tabList();

	var pass = true;

	var temp = create("input");
	attr(temp,"id","test");
	attr(temp,"type","hidden");
	append(document.body,temp);

	for(var i=0,len=arr.length;i<len;i++)
	{
		
		id("test").value=arr[i].innerHTML.replace(/\&nbsp\;/gi,"");

		var vaobj = new txjs.va.vamanager()

		var varule = {};

		varule["test"] = cellvarule["td" + getcolNum(parent(arr[i],3),arr[i])];
		
		vaobj.addoption(varule);
	
		vaobj.validate(function() {});

		if(!vaobj.getisok()){
		
			pass = false;
			break;
		}
		
	}

	if(i==len) return pass;

	var cellIndex = getcolNum(parent(arr[i],3),arr[i]),
	
	tdEditType = tdEditopt["td"+cellIndex] || "text";
	
	
	createInput(arr[i],tdEditType);

	setTimeout(function(){
		ctdElem = arr[i];
		cRow = parent(arr[i]);
		oldobj = ctdElem;
		setcRowColor(parent(ctdElem));
		
	},0);

	remove(temp);

	return pass;	
}

//获取列数据(Array)
function getCellData()
{
	//关闭有存在的编辑
	documentClick();
	var temp = [];
	//alert("尚未实现");
	each(celList(ctable,ctdElem),function(){
		temp.push(this.innerHTML.replace(/\&nbsp\;/gi,""));
	});
	return temp;
}

//获取表格行数据
function getRowData()
{
	//关闭有存在的编辑
	documentClick();
	var temp = [];
	//alert("尚未实现");
	each(tag("td",cRow),function(){
		temp.push(this.innerHTML.replace(/\&nbsp\;/gi,""));
	});

	return temp;
}

//设置只读
//[0,0]
//[0,"*"] 0列
//["*",0] 0行
function readOnly(optarr)
{
	if(!(optarr && optarr.constructor === Array) && optarr.length == 2) return;
	
	//表格列数
	var cellnum = tag("td",id(tableids.split(",")[0])).length / tag("tr",id(tableids.split(",")[0])).length,

	//td列表
	tdarr = tabList(),

	//将表格转换到二维数组
	arrTable = toArr(tdarr,cellnum);

	
	if(!optarr.inArray("*"))
	{	
       	//特殊单元格
	readOnlyTds.push(arrTable[optarr[1]][optarr[0]]);
	return;
	}

	//行只读
	if(optarr[0]=="*")
	{	
		each(arrTable[0],function(){
			readOnlyTds.push(this);
		});
		return;
	}

	if(optarr[1]=="*")
	{
		//列只读
		//表格行数
		var rownum = tdarr.length / cellnum,

		//列编号
		n = optarr[0];
		
		for(i=0;i<rownum;i++)
		{
		readOnlyTds.push(tdarr[n + (cellnum * i)]);
		}
		return;
	}
}

//设置表格的弹出层设置值方式
//obj 弹出层对象
//aopt 单元格配置,同只读单元格
function setPopup(obj,aopt)
{

	if(typeof obj != "string") 
	oPopups = obj;
	else
	oPopup = obj;
	//将需要弹出层设置的单元格设置为只读
	readOnly(aopt);
	//设置弹出层对象
	
}

//根据tableid获取相应的popup对象
function getPopup(sTableId)
{                          
	if(oPopup) return oPopup;
	if(!ctable) return;
	return oPopups[sTableId];
}

//设置当前单元格的值
function settdValue(value)
{
	if(ctdElem) ctdElem.innerHTML = value;
}

//配置信息
function setOption(opt)
{
	Object.extend(tdEditopt,opt);
}

//public
table.prototype = {
	
	//是否开启编辑
	enableedit : edited,

	//移动行
	moveRow:moveRow,

	delRow:delRow,
	
	newTopRow:newTopRow,
	
	newBottomRow:newBottomRow,

	getArrayData:getArrayData,

	getCellData:getCellData,

	getRowData:getRowData,

	//获取表格html
	getTableHtml:getTableHtml,

	readOnly:readOnly,

	setOption:setOption,

	documentClick:documentClick,

	//开始编辑时触发
	onEditOpen:function(fn){oncreate = fn;},

	//单元格输入结束触发
	onEditClose:function(fn){onreset = fn;},

	//添加列验证规则
	addCellRule:function(opt){enableva=true;cellvarule = opt;},


	addvaRule:function(opt){cellvarule = opt;},

	//共有多少行数据
	trCount:function(){
		var n=0;
		each(ids.split(","),function(){
			n += tag("tbody",id(this+""))[0].rows.length
		});

		return n;
		
	},
	vaTableData:vaTableData,
	setPopup:setPopup,
	settdValue:settdValue
};

return table.prototype;

}


